from datetime import datetime
from django.db import models
from django.db.models import Q
from django.contrib.auth.models import User
from tagging.fields import TagField

class PollManager(models.Manager):
	def _filters(self, filters):
		if filters is None:
			return { }
		return filters
	
	def get_query_set(self, filters=None):
		return super(PollManager, self).get_query_set().filter(**self._filters(filters))
	
	def open(self, filters=None):
		"Returns all the Polls with ``start`` in the past and ``end`` in the future (or blank)."
		return self.get_query_set(filters).filter(Q(end__isnull=True) | Q(end__gt=datetime.now()),
			start__isnull=False, start__lte=datetime.now()).order_by('-start')
			
	def ended(self, filters=None):
		" Returns all the Polls that have run but are now closed due to ``end`` being passed. "
		raise NotImplementedError
		
	def queued(self, filters=None):
		" Returns all the Polls that have a ``start`` in the future. "
		raise NotImplementedError
			
	def newest(self, filters=None):
		"Returns the most recently opened Poll."
		try:
			return self.open(filters)[0]
		except IndexError:
			return None

class Poll(models.Model):

	objects = PollManager()
	question = models.CharField(max_length=100)
	tags = TagField(blank=True)
	description = models.TextField(blank=True)
	start = models.DateTimeField(blank=True, null=True, help_text=u'Choose the date you\'d like this poll to start.')
	end = models.DateTimeField(blank=True, null=True, help_text=u'Leave blank to let this poll continue indefinitely.')
	
	def __unicode__(self):
		return self.question
		
	@models.permalink
	def get_submit_url(self):
		return ('pollster-vote', (), {})
		
	def is_open(self):
		return bool((self.start is not None) and (self.start <= datetime.now()) and (self.end is None or self.end > datetime.now()))
	is_open.short_description = u'open'
		
	def total_votes(self):
		return self.vote_set.count()
		
	class Admin:
		list_display = [u'question', u'start', u'end', u'tags', u'total_votes', u'is_open']
		list_filter = [u'start', u'end']
		search_fields = [u'question', u'tags', u'description']
		date_hierarchy = u'start'
		
class Choice(models.Model):
	poll = models.ForeignKey(Poll, edit_inline=models.TABULAR, min_num_in_admin=5, num_extra_on_change=5)
	choice = models.CharField(max_length=100, core=True)
	position = models.IntegerField(default=0)
	
	def get_percent(self):
		try:
 			return int(round(float(self.vote_set.count()) / self.poll.vote_set.count() * 100))
		except ZeroDivisionError:
			return 0
	
	def __unicode__(self):
		return self.choice
		
	class Meta:
		ordering = ['position', 'choice']
		
	class Admin:
		pass
		
class Vote(models.Model):
	poll = models.ForeignKey(Poll, editable=False)
	choice = models.ForeignKey(Choice)
	date = models.DateTimeField(editable=False, default=datetime.now())
	user = models.ForeignKey(User, null=True)
	ip_address = models.IPAddressField(editable=False, blank=True, null=True)
	
	def __unicode__(self):
		return u'%s +1' % self.choice
		
	def save(self):
		self.poll = self.choice.poll
		super(Vote, self).save()
	
	class Meta:
		ordering = ['-date']
		
	class Admin:
		pass